/**
 *  
 */
package com.cfjjc.gz.common.action;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.base.JRBaseReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.util.JRLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.util.ServletContextAware;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 
 */
public abstract class BaseAction extends ActionSupport implements SessionAware,
		ServletRequestAware, ServletResponseAware, ServletContextAware {

	protected final Log logger = LogFactory.getLog(getClass());

	protected Map<String, Object> session;

	protected HttpServletRequest request;

	protected HttpServletResponse response;

	protected ServletContext context;

	protected List rows = new ArrayList();

	protected Integer total = new Integer(0);

	/**
	 * 自定义几个action处理返回结果类型
	 */

	// 模块首页
	public static final String INDEX = "index";

	// 信息提示页面
	public static final String INFO = "info";

	// 列表页面
	public static final String LIST = "list";

	// 树状页面
	public static final String TREE = "tree";

	// 树节点页面
	public static final String TREE_NODE = "tree_node";

	// 操作完成后返回页面(如insert，update等操作后向页面返回业务模型数据)
	public static final String OPE_INFO = "ope_info";

	// 对于同步操作发生异常后的页面导向
	public static final String ERROR_PAGE = "error_page";
	
	// 对于AJAX上传文件操作发生异常后的页面导向
	public static final String WORKFLOW_ERROR = "workflow_error";
	
	// 审核模块首页
	public static final String CHECK_INDEX = "check_index";
	
	// 审核模块编辑页面
	public static final String CHECK_INPUT = "check_input";
	
	// 审核模块明细页面
	public static final String CHECK_INFO = "check_info";

	// 打印页面
	public static final String PRINT = "print";
	
	// 没有记录
	public static final String NODATA = "nodata";

	// 选择页面
	public static final String SELECT = "select";
	
	// 下载页面
	public static final String DOWN_LOAD = "down_load";

	/**
	 * 记录复选框选择的值列表,用于批量操作.保存的值一般为记录的主键字段
	 */
	protected String[] id = new String[0];

	/**
	 * 生成报表时,可存放报表标题,表头,制表人,时间等需要参数的Map
	 */
	protected Map reportMap = new Hashtable();

	/**
	 * 定义导出文件的格式
	 */
	protected String exportType = "XLS";

	/**
	 * 给查询起的一个名字，为了区分开在session中存放的查询结果对象
	 */
	protected String QUERY_NAME;

	/**
	 * 定义用于生成报表的jasper文件的路径
	 */
	protected String jasperFilePath;

	/**
	 * 导出的文件名称
	 */
	protected String exportFileName;

	/**
	 * 输出格式参数
	 */
	protected String format = "HTML";

	/**
	 * 页面类型,见PageTypeConst中定义的常数
	 */
	protected int pageType;
	
	/**
	 * 操作类型,见SystemConst中定义的常数
	 */
	protected int operationType;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.opensymphony.xwork2.ActionSupport#addFieldError(java.lang.String,
	 * java.lang.String)
	 */
	@Override
	public void addFieldError(String fieldName, String errorMessage) {
		this.addActionError(errorMessage);
		super.addFieldError(fieldName, errorMessage);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.interceptor.SessionAware#setSession(java.util.Map)
	 */
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.interceptor.ServletResponseAware#setServletResponse
	 * (javax.servlet.http.HttpServletResponse)
	 */
	public void setServletResponse(HttpServletResponse session) {
		this.response = session;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.struts2.interceptor.ServletRequestAware#setServletRequest(
	 * javax.servlet.http.HttpServletRequest)
	 */
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	/**
	 * @return the session
	 */
	public Map<String, Object> getSession() {
		return session;
	}

	/**
	 * @return the request
	 */
	public HttpServletRequest getRequest() {
		return request;
	}

	/**
	 * @return the response
	 */
	public HttpServletResponse getResponse() {
		return response;
	}

	/**
	 * @return the rows
	 */
	public abstract List getRows();

	/**
	 * @param rows
	 *            the rows to set
	 */
	public void setRows(List rows) {
		this.rows = rows;
	}

	/**
	 * @return the total
	 */
	public abstract Integer getTotal();

	/**
	 * @return the id
	 */
	public String[] getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(String[] id) {
		this.id = id;
	}

	/**
	 * @return the reportMap
	 */
	public Map getReportMap() {
		return reportMap;
	}

	/**
	 * @param reportMap
	 *            the reportMap to set
	 */
	public void setReportMap(Map reportMap) {
		this.reportMap = reportMap;
	}

	/**
	 * @return the exportType
	 */
	public String getExportType() {
		return exportType;
	}

	/**
	 * @param exportType
	 *            the exportType to set
	 */
	public void setExportType(String exportType) {
		this.exportType = exportType;
	}

	/**
	 * @return the qUERY_NAME
	 */
	public String getQUERY_NAME() {
		return QUERY_NAME;
	}

	/**
	 * @param qUERYNAME
	 *            the qUERY_NAME to set
	 */
	public void setQUERY_NAME(String qUERYNAME) {
		QUERY_NAME = qUERYNAME;
	}

	/**
	 * @return the jasperFilePath
	 */
	public String getJasperFilePath() {
		return jasperFilePath;
	}

	/**
	 * @param jasperFilePath
	 *            the jasperFilePath to set
	 */
	public void setJasperFilePath(String jasperFilePath) {
		this.jasperFilePath = jasperFilePath;
	}

	/**
	 * @return the exportFileName
	 */
	public String getExportFileName() {
		return exportFileName;
	}

	/**
	 * @param exportFileName
	 *            the exportFileName to set
	 */
	public void setExportFileName(String exportFileName) {
		this.exportFileName = exportFileName;
	}

	/**
	 * @return the format
	 */
	public String getFormat() {
		return format;
	}

	/**
	 * @param format
	 *            the format to set
	 */
	public void setFormat(String format) {
		this.format = format;
	}

	public int getPageType() {
		return pageType;
	}

	public void setPageType(int pageType) {
		this.pageType = pageType;
	}

	public int getOperationType() {
		return operationType;
	}

	public void setOperationType(int operationType) {
		this.operationType = operationType;
	}

	/**
	 * @param context
	 */
	public void setServletContext(ServletContext context) {
		this.context = context;
	}

	/**
	 * 把对应的javabean转换成map形式
	 * 
	 * @param bean
	 * @return
	 * @throws IntrospectionException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static Map convertBean(Object bean) throws IntrospectionException,
			IllegalAccessException, InvocationTargetException {
		Class cla = bean.getClass();
		Map returnMap = new HashMap();
		BeanInfo beanInfo = Introspector.getBeanInfo(cla);

		PropertyDescriptor[] propertyDescriptors = beanInfo
				.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++) {
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();
			if (!propertyName.equals("class")) {
				Method readMethod = descriptor.getReadMethod();
				Object result = readMethod.invoke(bean, new Object[0]);
				if (result != null) {
					returnMap.put(propertyName, result);
				} else {
					returnMap.put(propertyName, "");
				}
			}
		}
		return returnMap;
	}
	
	/**
	 *  填充jasper报表文件
	 * @param jasperFilePath 
	 * @param exportExcelFileName
	 * @param rows
	 * @throws Exception
	 */
	public static void exportExcel(String jasperFilePath, String exportExcelFileName, Collection rows) throws Exception { 

		String reportFileName = ServletActionContext.getServletContext().getRealPath(jasperFilePath);
		File reportFile = new File(reportFileName);
		 if (!reportFile.exists())
				throw new Exception("jasper not found. The report design must be compiled first.");

		InputStream is = new FileInputStream(reportFile);
		HttpServletResponse response = ServletActionContext.getResponse();

		JRDataSource ds = new JRBeanCollectionDataSource(rows,false);
		JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);


		Field margin = JRBaseReport.class.getDeclaredField("leftMargin");
		margin.setAccessible(true);
		margin.setInt(jasperReport, 0);
		margin = JRBaseReport.class.getDeclaredField("topMargin");
		margin.setAccessible(true);
		margin.setInt(jasperReport, 0);
		margin = JRBaseReport.class.getDeclaredField("bottomMargin");
		margin.setAccessible(true);
		margin.setInt(jasperReport, 0);
		Field pageHeight = JRBaseReport.class.getDeclaredField("pageHeight");
		pageHeight.setAccessible(true);
		pageHeight.setInt(jasperReport, 2147483647);
		
		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, ds);
		JRXlsExporter exporter = new JRXlsExporter();
		// excel输出
		ByteArrayOutputStream oStream = new ByteArrayOutputStream();
		exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
		exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, oStream);
		exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE); // 删除记录最下面的空行
		exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);// 删除多余的ColumnHeader
		exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);// 显示边框
		exporter.exportReport();

		byte[] bytes = oStream.toByteArray();

		if (bytes != null && bytes.length > 0) {
			response.reset();
			response.setContentType("application/vnd.ms-excel");
			String fileName = new String(exportExcelFileName.getBytes("GBK"), "ISO8859_1");
			response.setHeader("Content-disposition", "attachment; filename=" + fileName);
			response.setContentLength(bytes.length);
			response.setCharacterEncoding("UTF-8");
			ServletOutputStream ouputStream = response.getOutputStream();
			ouputStream.write(bytes, 0, bytes.length);
			ouputStream.flush();
			ouputStream.close();
		}
	 }
	
}
